home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / setup / vbnet / 17 controls / customcontroldemo / countdownlabel.vb < prev    next >
Encoding:
Text File  |  2002-03-16  |  3.4 KB  |  105 lines

  1. Imports System.Threading
  2.  
  3. ' a control that uses multithreading
  4.  
  5. Public Class CountdownLabel
  6.     Inherits System.Windows.Forms.Label
  7.  
  8.     ' a delegate that points to the SetText procedure.
  9.     Delegate Sub SetTextDelegate(ByVal Text As String)
  10.  
  11.     ' an instance of this delegate that points to SetText procedure
  12.     Dim SetTextMarshaller As SetTextDelegate = AddressOf Me.SetText
  13.  
  14.     ' internal counter for numbers of left seconds.
  15.     Dim secondsLeft As Integer
  16.     ' end time
  17.     Dim endTime As Date
  18.     ' the thread object (if nothing, no other thread is running).
  19.     Dim thr As Thread
  20.  
  21.     ' the method that starts the countdown
  22.  
  23.     Sub StartCountdown(ByVal seconds As Integer)
  24.         ' wait until all variables can be accessed safely
  25.         SyncLock Me
  26.             ' save values where the other thread can access them.
  27.             secondsLeft = seconds
  28.             endTime = Now.AddSeconds(seconds)
  29.  
  30.             ' create the new thread and run the procedure on that thread
  31.             ' but only if the thread isn't running already
  32.             If (thr Is Nothing) Then
  33.                 thr = New Thread(AddressOf CountProc)
  34.                 thr.Start()
  35.             End If
  36.         End SyncLock
  37.  
  38.         ' display the initial value in the label
  39.         SetText(CStr(seconds))
  40.     End Sub
  41.  
  42.     ' this method stops the countdown
  43.  
  44.     Sub StopCountdown()
  45.         SyncLock Me
  46.             ' This will implicitly cause the code in CountProc to exit
  47.             endTime = Now
  48.         End SyncLock
  49.     End Sub
  50.  
  51.     ' This procedure is just a wrapper for a simple property set, and must run
  52.     ' on the control's creation thread. The other thread(s) must call it through
  53.     ' SetTextDelegate 
  54.  
  55.     Private Sub SetText(ByVal Text As String)
  56.         Me.Text = Text
  57.     End Sub
  58.  
  59.     ' This procedure runs on another thread.
  60.  
  61.     Private Sub CountProc()
  62.         Do
  63.             ' ensure that this is the only thread that is accessing variables.
  64.             SyncLock Me
  65.                 ' get the number of seconds left.
  66.                 Dim secs As Integer = CInt(endTime.Subtract(Now).TotalSeconds)
  67.  
  68.                 ' if different from current value, update the Text property.
  69.                 If secs <> secondsLeft Then
  70.                     ' never display negative numbers
  71.                     If secs < 0 Then secs = 0
  72.                     secondsLeft = secs
  73.  
  74.                     ' set the Text property with current number of seconds
  75.                     Dim args() As Object = {CStr(secondsLeft)}
  76.                     MyBase.Invoke(SetTextMarshaller, args)
  77.  
  78.                     ' terminate the thread if countdown is over
  79.                     If secondsLeft <= 0 Then
  80.                         ' signal that no thread is running, and exit
  81.                         thr = Nothing
  82.                         Exit Do
  83.                     End If
  84.  
  85.                 End If
  86.             End SyncLock
  87.  
  88.             ' wait for 100 milliseconds
  89.             Thread.Sleep(100)
  90.         Loop
  91.     End Sub
  92.  
  93.     ' kill the other thread if the control is being destroyed.
  94.  
  95.     Protected Overrides Sub OnHandleDestroyed(ByVal e As System.EventArgs)
  96.         SyncLock Me
  97.             If Not (thr Is Nothing) AndAlso thr.IsAlive Then
  98.                 thr.Abort()
  99.                 thr.Join()
  100.             End If
  101.         End SyncLock
  102.         MyBase.OnHandleDestroyed(e)
  103.     End Sub
  104. End Class
  105.